package com.zhoug.common.utils;

import android.os.Handler;
import android.os.Looper;


import java.util.concurrent.TimeUnit;

import androidx.annotation.NonNull;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;

/**
 * 定时执行任务
 *支持倒计时、重复执行、生命周期绑定等功能.
 * @author: zhoug
 * @since: 2025-07-21
 */
public class ZTaskTimer {
    private static final String TAG = ">>>ZTaskTimer";
    private static final int STATE_INIT = 0;
    private static final int STATE_STARTED = 1;
    private static final int STATE_PAUSE = 2;
    /**
     * 倒计时模式,不计时
     */
    public static final int COUNTDOWN_MODE_NONE = 0;
    /**
     * 倒计时模式,正向计时
     */
    public static final int COUNTDOWN_MODE_INCREASE = 1;
    /**
     * 倒计时模式,倒计时
     */
    public static final int COUNTDOWN_MODE_MINUS = 2;
    /**
     * 任务执行间隔,延迟多长时间执行 单位毫秒 {@link TimeUnit#MILLISECONDS}
     */
    private long mInterval;
    /**
     * 任务重复执行次数,0:不重复,小于0:无限次,大于0:执行指定的次数
     */
    private int mRepeatCount = 0;
    /**
     * 倒计时模式
     * {@link #COUNTDOWN_MODE_NONE,#COUNTDOWN_MODE_INCREASE,#COUNTDOWN_MODE_MINUS}
     */
    private int mCountdownMode = COUNTDOWN_MODE_NONE;
    /**
     * 监听器
     */
    private TimerListener mTimerListener;
    /**
     * 需要执行的任务
     */
    private Runnable mTask;
    private final Handler mHandler = new Handler(Looper.getMainLooper());
    private long mTaskStartTime;//上次任务开始时间
    private Runnable mTimerTask;//计时任务
    private int mCompleteCount;//完成任务次数
    /**
     * {@link #STATE_INIT,#STATE_STARTED ,#STATE_PAUSE}
     */
    private int mState = STATE_INIT;//任务状态
    private long mCountdown;//倒计时,每轮任务都会从新倒计时
    private long mDelayMillis;//实际延迟执行的时间,暂停后重新启动时,会变化


    /**
     * 设置任务执行间隔
     *
     * @param interval 任务执行间隔 单位毫秒 {@link TimeUnit#MILLISECONDS}
     */
    public ZTaskTimer setInterval(long interval) {
        this.mInterval = interval;
        return this;
    }

    /**
     * 设置任务重复执行次数
     *
     * @param repeatCount 任务重复执行次数 0:不重复,小于0:无限次,大于0:执行指定的次数
     */
    public ZTaskTimer setRepeatCount(int repeatCount) {
        this.mRepeatCount = repeatCount;
        return this;
    }

    /**
     * 设置倒计时模式
     * {@link #COUNTDOWN_MODE_NONE,#COUNTDOWN_MODE_INCREASE,#COUNTDOWN_MODE_MINUS}
     *
     * @param countdownMode 倒计时模式
     */
    public ZTaskTimer setCountdownMode(int countdownMode) {
        this.mCountdownMode = countdownMode;
        return this;
    }

    /**
     * 设置监听器
     *
     * @param listener
     * @return
     */
    public ZTaskTimer setTimerListener(TimerListener listener) {
        this.mTimerListener = listener;
        return this;
    }

    /**
     * 设置需要执行的任务
     *
     * @param task 需要执行的任务
     */
    public ZTaskTimer setTask(@NonNull Runnable task) {
        this.mTask = task;
        return this;
    }

    /**
     * 根据生命周期管理
     *
     * @param owner
     * @return
     */
    public ZTaskTimer setLifecycleOwner(@NonNull LifecycleOwner owner) {
        owner.getLifecycle().addObserver(new DefaultLifecycleObserver() {

            @Override
            public void onResume(@NonNull LifecycleOwner owner) {
                if (mState != STATE_PAUSE) return;
                long elapsedTime = System.currentTimeMillis() - mTaskStartTime;
                if (elapsedTime >= mDelayMillis) {
                    executeTask();
                } else {
                    start(mDelayMillis - elapsedTime);
                }
            }

            @Override
            public void onPause(@NonNull LifecycleOwner owner) {
                removeTimeTask();
                mState = STATE_PAUSE;
            }

            @Override
            public void onDestroy(@NonNull LifecycleOwner owner) {
                stop();
            }
        });
        return this;
    }

    /**
     * 开始执行任务
     */
    public void start() {
        start(mInterval);
    }

    /**
     * 开始任务
     *
     * @param interval
     */
    private void start(long interval) {
        if (mState == STATE_STARTED) {
            LogUtils.w(TAG, "任务已经启动");
            return;
        }
        if (mTask == null) {
            throw new IllegalArgumentException("没有设置任务,请先调用setTask");
        }
        //执行间隔小于等于0时直接执行
        if (interval <= 0) {
            mHandler.post(mTask);
            return;
        }
        mDelayMillis=interval;
        //移除上次的任务
        removeTimeTask();
        //记录任务开始时间
        mTaskStartTime = System.currentTimeMillis();
        //创建计时任务
        mTimerTask = () -> {
            if (mCountdownMode == COUNTDOWN_MODE_NONE) {
                executeTask();
            } else {
                long time = System.currentTimeMillis() - mTaskStartTime;
                if (time >= mDelayMillis) {
                    executeTask();
                } else {
                    if (mTimerListener != null) {
                        if (mCountdownMode == COUNTDOWN_MODE_INCREASE) {
                            mCountdown++;
                        } else {
                            mCountdown--;
                        }
                        mTimerListener.onCountDown(mCountdown);
                    }
                    mHandler.postDelayed(mTimerTask, 1000);
                }
            }
        };
        mState = STATE_STARTED;
        //定时执行
        if (mCountdownMode == COUNTDOWN_MODE_NONE) {
            mHandler.postDelayed(mTimerTask, mDelayMillis);
        } else {
            //初始化计时器
            if (mCountdownMode == COUNTDOWN_MODE_INCREASE) {
                mCountdown = (mInterval-mDelayMillis)/1000;
            } else {
                mCountdown = mDelayMillis / 1000;
            }
            if (mTimerListener != null) {
                mTimerListener.onCountDown(mCountdown);
            }
            mHandler.postDelayed(mTimerTask, 1000);
        }

    }

    /**
     * 执行任务
     */
    private void executeTask() {
        //任务执行次数加1
        mCompleteCount++;
        if (mTimerListener != null) {
            mTimerListener.onCountDown(mCountdownMode == COUNTDOWN_MODE_INCREASE ? mInterval / 1000 : 0);
        }
        mTask.run();
        mCountdown = 0;
        mState=STATE_INIT;
        //任务是否需要继续执行
        boolean continueTask = mRepeatCount < 0 || mRepeatCount - mCompleteCount > 0;
        //监听回掉
        if (mTimerListener != null) {
            mTimerListener.onExecuted(mCompleteCount, !continueTask);
        }
        if (continueTask) {
            //重新开始任务
            start();
        }

    }

    /**
     * 移除计时任务
     */
    private void removeTimeTask() {
        if (mTimerTask != null) {
            mHandler.removeCallbacks(mTimerTask);
        }
    }

    /**
     * 停止执行,
     */
    public void stop() {
        removeTimeTask();
        mState = STATE_INIT;
        mCompleteCount = 0;
        mTaskStartTime = 0;
        mCountdown = 0;
        mDelayMillis = 0;
        mTimerTask = null;
    }

    /**
     * 监听器
     */
    public interface TimerListener {
        /**
         * 倒计时,每轮任务都会从新倒计时
         *
         * @param countDown 倒计时
         */
        void onCountDown(long countDown);

        /**
         * 任务执行后回掉
         *
         * @param taskCount 任务执行次数
         * @param end       是否已经全部完成
         */
        void onExecuted(int taskCount, boolean end);
    }

}
